package common

import (
	"gorm.io/gorm"
	"os"
	"path"
	"seven-admin/app/admin/schemas/query"
	"seven-admin/app/admin/schemas/req"
	"seven-admin/app/admin/schemas/resp"
	"seven-admin/app/collection/common"
	"seven-admin/core"
	"seven-admin/core/config"
	"seven-admin/core/response"
	"seven-admin/util"
)

type AlbumService interface {
	AlbumList(page req.PageReq, listReq req.CommonAlbumListReq, auth *req.AuthReq) (res response.PageResp, e error)
	AlbumRename(id uint, name string, auth *req.AuthReq) (e error)
	AlbumMove(ids []uint, cid int, auth *req.AuthReq) (e error)
	AlbumAdd(addReq req.CommonAlbumAddReq, auth *req.AuthReq) (res uint, e error)
	AlbumDel(ids []uint, auth *req.AuthReq) (e error)
	AlbumDetail(name string, auth *req.AuthReq) (res resp.CommonUploadFileResp, e error)
	CateList(listReq req.CommonCateListReq, auth *req.AuthReq) (mapList []interface{}, e error)
	CateAdd(addReq req.CommonCateAddReq, auth *req.AuthReq) (e error)
	CateRename(id uint, name string, auth *req.AuthReq) (e error)
	CateDel(id uint, auth *req.AuthReq) (e error)
}

// albumService 相册服务实现类
type albumService struct {
	db *gorm.DB
}

func (a albumService) AlbumList(page req.PageReq, listReq req.CommonAlbumListReq, auth *req.AuthReq) (res response.PageResp, e error) {
	//TODO implement me
	// 分页信息
	limit := page.PageSize
	offset := page.PageSize * (page.PageNo - 1)
	// 查询
	albumModel := a.db.Model(&common.Album{})
	albumModel = query.AuthQuery(albumModel, auth)
	if listReq.Cid > 0 {
		albumModel = albumModel.Where("cid = ?", listReq.Cid)
	}
	if listReq.Name != "" {
		albumModel = albumModel.Where("name like ?", "%"+listReq.Name+"%")
	}
	if listReq.Type > 0 {
		albumModel = albumModel.Where("type = ?", listReq.Type)
	}
	// 总数
	var count int64
	err := albumModel.Count(&count).Error
	if e = response.CheckErr(err, "AlbumList Count err"); e != nil {
		return
	}
	// 数据
	var albums []common.Album
	err = albumModel.Limit(limit).Offset(offset).Order("id desc").Find(&albums).Error
	if e = response.CheckErr(err, "AlbumList Find err"); e != nil {
		return
	}
	albumResps := []resp.CommonAlbumListResp{}
	response.Copy(&albumResps, albums)
	// TODO: engine默认local
	engine := "local"
	for i := 0; i < len(albumResps); i++ {
		if engine == "local" {
			albumResps[i].Path = path.Join(config.Env.PublicPrefix, albums[i].Uri)
		} else {
			// TODO: 其他engine
		}
		albumResps[i].Uri = util.UrlUtil.ToAbsoluteUrl(albums[i].Uri)
		albumResps[i].Size = util.ServerUtil.GetFmtSize(uint64(albums[i].Size))
	}
	return response.PageResp{
		PageNo:   page.PageNo,
		PageSize: page.PageSize,
		Count:    count,
		Lists:    albumResps,
	}, nil
}

func (a albumService) AlbumRename(id uint, name string, auth *req.AuthReq) (e error) {
	//TODO implement me
	var album common.Album
	sql := a.db.Model(&common.Album{})
	sql = query.AuthQuery(sql, auth)
	err := sql.Where("id = ?", id).Limit(1).First(&album).Error
	if e = response.CheckErrDBNotRecord(err, "文件丢失！"); e != nil {
		return
	}
	if e = response.CheckErr(err, "AlbumRename First err"); e != nil {
		return
	}
	album.Name = name
	err = a.db.Save(&album).Error
	e = response.CheckErr(err, "AlbumRename Save err")
	return
}

func (a albumService) AlbumMove(ids []uint, cid int, auth *req.AuthReq) (e error) {
	//TODO implement me
	var albums []common.Album
	sql := a.db.Model(&common.Album{})
	sql = query.AuthQuery(sql, auth)
	err := sql.Where("id in ?", ids).Find(&albums).Error
	if e = response.CheckErr(err, "AlbumMove Find err"); e != nil {
		return
	}
	if len(albums) == 0 {
		return response.AssertArgumentError.Make("文件丢失！")
	}
	if cid > 0 {
		csql := a.db.Model(&common.AlbumCate{})
		csql = query.AuthQuery(csql, auth)
		err = csql.Where("id = ?", cid).Limit(1).First(&common.AlbumCate{}).Error
		if e = response.CheckErrDBNotRecord(err, "类目已不存在！"); e != nil {
			return
		}
		if e = response.CheckErr(err, "AlbumMove First err"); e != nil {
			return
		}
	}
	asql := a.db.Model(&common.Album{})
	asql = query.AuthQuery(asql, auth)
	err = asql.Where("id in ?", ids).UpdateColumn("cid", cid).Error
	e = response.CheckErr(err, "AlbumMove UpdateColumn err")
	return
}

func (a albumService) AlbumAdd(addReq req.CommonAlbumAddReq, auth *req.AuthReq) (res uint, e error) {
	//TODO implement me
	var alb common.Album
	response.Copy(&alb, addReq)
	alb.TenantId = auth.TenantId
	err := a.db.Create(&alb).Error
	if e = response.CheckErr(err, "AlbumAdd Create err"); e != nil {
		return
	}
	return alb.ID, nil
}

func (a albumService) AlbumDel(ids []uint, auth *req.AuthReq) (e error) {
	//TODO implement me
	var albums []common.Album
	sql := a.db.Model(&common.Album{})
	sql = query.AuthQuery(sql, auth)
	err := sql.Where("id in ?", ids).Find(&albums).Error
	if e = response.CheckErr(err, "AlbumDel Find err"); e != nil {
		return
	}
	if len(albums) == 0 {
		return response.AssertArgumentError.Make("文件丢失！")
	}
	//if deptId != cate.DepartmentID && deptId != config.AdminConfig.SuperDepartmentId {
	//	return response.AssertArgumentError.Make("无权限,不能删除！")
	//}
	var nalbums []common.Album
	for i := 0; i < len(albums); i++ {
		if auth.IsSuperAdmin {
			nalbums = append(nalbums, albums[i])
			continue
		}
		if auth.TenantId != albums[i].TenantId && !auth.IsSuperTenant {
			continue
		}
		nalbums = append(nalbums, albums[i])
	}
	err = a.db.Delete(&nalbums).Error
	e = response.CheckErr(err, "AlbumDel UpdateColumn err")
	// 删除文件
	for _, album := range nalbums {
		dir, _ := os.Getwd()
		p := path.Join(dir, config.Env.UploadDirectory)
		if err := util.FileUtil.RemoveFile(path.Join(p, album.Uri)); err != nil {
			core.Logger.Errorf("AlbumDel RemoveFile err: err=[%+v]", err)
		}
	}
	return
}

func (a albumService) AlbumDetail(name string, auth *req.AuthReq) (res resp.CommonUploadFileResp, e error) {
	//TODO implement me
	var album common.Album
	sql := a.db.Model(&common.Album{})
	sql = query.AuthQuery(sql, auth)
	err := sql.Where("name = ? or uri = ?", name, name).First(&album).Error
	if e = response.CheckErrDBNotRecord(err, "文件丢失！"); e != nil {
		return
	}
	if e = response.CheckErr(err, "AlbumDetail First err"); e != nil {
		return
	}
	response.Copy(&res, album)
	// TODO: engine默认local
	//engine := "local"
	res.Path = path.Join(config.Env.PublicPrefix, album.Uri)
	res.Uri = util.UrlUtil.ToAbsoluteUrl(album.Uri)
	res.Size = album.Size
	return
}

func (a albumService) CateList(listReq req.CommonCateListReq, auth *req.AuthReq) (mapList []interface{}, e error) {
	//TODO implement me
	var cates []common.AlbumCate
	sql := a.db.Model(&common.AlbumCate{})
	sql = query.AuthQuery(sql, auth)
	cateModel := sql.Order("id desc")
	if listReq.Type > 0 {
		cateModel = cateModel.Where("type = ?", listReq.Type)
	}
	if listReq.Name != "" {
		cateModel = cateModel.Where("name like ?", "%"+listReq.Name+"%")
	}
	err := cateModel.Find(&cates).Error
	if e = response.CheckErr(err, "CateList Find err"); e != nil {
		return
	}
	cateResps := []resp.CommonCateListResp{}
	response.Copy(&cateResps, cates)
	return util.ArrayUtil.ListToTree(
		util.ConvertUtil.StructsToMaps(cateResps), "id", "pid", "children"), nil
}

func (a albumService) CateAdd(addReq req.CommonCateAddReq, auth *req.AuthReq) (e error) {
	//TODO implement me
	var cate common.AlbumCate
	response.Copy(&cate, addReq)
	cate.TenantId = auth.TenantId
	err := a.db.Create(&cate).Error
	e = response.CheckErr(err, "CateAdd Create err")
	return
}

func (a albumService) CateRename(id uint, name string, auth *req.AuthReq) (e error) {
	//TODO implement me
	var cate common.AlbumCate
	sql := a.db.Model(&common.AlbumCate{})
	sql = query.AuthQuery(sql, auth)
	err := sql.Where("id = ?", id).Limit(1).First(&cate).Error
	if e = response.CheckErrDBNotRecord(err, "分类已不存在！"); e != nil {
		return
	}
	if e = response.CheckErr(err, "CateRename First err"); e != nil {
		return
	}
	cate.Name = name
	err = a.db.Save(&cate).Error
	e = response.CheckErr(err, "CateRename Save err")
	return
}

func (a albumService) CateDel(id uint, auth *req.AuthReq) (e error) {
	//TODO implement me
	var cate common.AlbumCate
	csql := a.db.Model(&common.AlbumCate{})
	csql = query.AuthQuery(csql, auth)
	err := csql.Where("id = ? AND is_delete = ?", id, 0).Limit(1).First(&cate).Error
	if e = response.CheckErrDBNotRecord(err, "分类已不存在！"); e != nil {
		return
	}
	if e = response.CheckErr(err, "CateDel First err"); e != nil {
		return
	}
	asql := a.db.Model(&common.Album{})
	asql = query.AuthQuery(asql, auth)
	r := asql.Where("cid = ? AND is_delete = ?", id, 0).Limit(1).Find(&common.Album{})
	if e = response.CheckErr(r.Error, "CateDel Find err"); e != nil {
		return
	}
	if r.RowsAffected > 0 {
		return response.AssertArgumentError.Make("当前分类正被使用中,不能删除！")
	}
	//cate.IsDelete = 1
	//cate.DeleteTime = time.Now().Unix()
	if auth.TenantId != cate.TenantId && !auth.IsSuperTenant {
		return response.AssertArgumentError.Make("无权限,不能删除！")
	}
	err = a.db.Delete(&cate).Error
	e = response.CheckErr(err, "CateDel Save err")
	return
}

// NewAlbumService 初始化
func NewAlbumService(db *gorm.DB) AlbumService {
	return &albumService{db: db}
}
